package org.piggy.client.support.dubbo;

import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.spring.ServiceBean;
import org.apache.dubbo.config.spring.context.event.ServiceBeanExportedEvent;
import org.piggy.client.core.scanner.ApiAnnotationScanner;
import org.piggy.client.autoconfigure.ApiProperties;
import org.piggy.client.support.AbstractClientRegisterManager;
import org.piggy.common.config.ServiceDefinition;
import org.piggy.common.config.ServiceInstance;
import org.piggy.common.utils.NetUtil;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import javax.annotation.Nonnull;
import java.util.HashSet;
import java.util.Set;

@Slf4j
public class DubboClientRegisterManager extends AbstractClientRegisterManager implements ApplicationListener<ApplicationEvent> {

    private final Set<Object> set = new HashSet<>();

    public DubboClientRegisterManager(ApiProperties apiProperties) {
        super(apiProperties);
    }

    @Override
    public void onApplicationEvent(@Nonnull ApplicationEvent applicationEvent) {
        if (applicationEvent instanceof ServiceBeanExportedEvent) {
            ServiceBean<?> serviceBean = ((ServiceBeanExportedEvent) applicationEvent).getServiceBean();
            doRegisterDubbo(serviceBean);
        } else if (applicationEvent instanceof ApplicationStartedEvent) {
            log.info("dubbo api started");
        }
    }

    private void doRegisterDubbo(ServiceBean<?> serviceBean) {
        Object bean = serviceBean.getRef();

        if (set.contains(bean)) {
            return;
        }

        ServiceDefinition serviceDefinition = ApiAnnotationScanner.getInstance().scanner(bean, serviceBean);

        if (serviceDefinition == null) {
            return;
        }

        serviceDefinition.setEnvType(getApiProperties().getEnv());

        String localIp = NetUtil.getLocalIp();
        int port = serviceBean.getProtocol().getPort();
        String serviceName = serviceDefinition.getServiceName();
        String version = serviceDefinition.getVersion();

        //服务实例
        ServiceInstance serviceInstance = makeServiceInstance(localIp, port, serviceName, version);

        register(serviceDefinition, serviceInstance);

        set.add(bean);
    }
}
